/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *                                                                           *
 *                          Copyright (c) 2010                               *
 *                  Alen Stojanov [ ioi.alen@gmail.com ]                     *
 *                Jacobs University Bremen, Bremen, Germany                  *
 *                                                                           *
 *                          All Rights Reserved.                             *
 *                                                                           *
 *    Permission to use, copy, modify and distribute this software and       *
 *    its documentation is hereby granted, provided that both the            *
 *    copyright notice and this permission notice appear in all copies of    *
 *    the software, derivative works or modified versions, and any           *
 *    portions thereof, and that both notices appear in supporting           *
 *    documentation.                                                         *
 *                                                                           *
 *    This code is distributed in the hope that it will be useful, but       *
 *    WITHOUT ANY WARRANTY; without even the implied warranty of             *
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS       *
 *    DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER          *
 *    RESULTING FROM THE USE OF THIS SOFTWARE.                               *
 *                                                                           *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#ifndef TSVIEW_H
#define TSVIEW_H

#include <QtGui/QWidget>
#include <QStringListModel>
#include <QListWidgetItem>
#include <QProgressBar>
#include <QThread>

#include "gllinegraph.h"
#include "glpreview.h"
#include "gllspgraph.h"
#include "tsdata.h"

#include "ui_tsview.h"

class TSView;

/**
 * @class TSDataRead
 * @author Alen Stojanov, October 2010
 *
 * @brief Read the imported data into a thread
 *
 * This class is an auxiliary class used for reading the
 * data from the input file into the main GUI. The only
 * purpose is to make sure that the system will not
 * hang while a huge chunk of data is read.
 */
class TSDataRead : public TSThread
{
     Q_OBJECT

private:
     /**
      * The tsview parent of the thread
      */
     TSView* tsview;
     /**
      * List of fileNames that will be read by the thread
      */
     QStringList fileNames;
     /**
      * Data type of the file input
      */
     TSData::TSDataType dataType;
     /**
      * Pointer of the map of tsdata classes in TSView
      */
     QMap<QString, TSData*> *mapNames2TSData;

public:
     /**
      * @brief Construct threaded data read by list of files, data type and the current view
      *
      * @param fileNames	List of file names that are about to be read
      * @param dataType		The type of file input of the specified file list
      * @param tsview		Reference of the main tsview object
      */
     TSDataRead(QStringList fileNames, TSData::TSDataType dataType, TSView* tsview);
     /**
      * Default destructor
      */
     ~TSDataRead();

protected:
     /**
      * @brief Main thread loop
      */
     void run();
};

/**
 * @class TSView
 * @author Alen Stojanov, September 2010
 *
 * @brief The subwindow rendering particular TS
 *
 * The TSView class is the core component of the TSRenderer that
 * coordinates all the other widgets in the rendering process of
 * the time series. It contains all the settings and all the tools
 * to manipulate and visualize the time series data. It also serves
 * as the central coordination body for all the signals and slots.
 * If any widget has a particular signal / slot, those have to
 * be transmitted throguh the tsview class, and then those will be
 * sent to the other particular widgets.
 */
class TSView : public QWidget
{
	Q_OBJECT

private:
	/**
	 * The pre-defined graphical UI
	 */
	Ui::TSViewClass ui;
	/**
	 * Main OpenGL graph of the Time Series
	 */
	GLLineGraph *glLineGraph;
	/**
	 * Show an overview of all time series listed
	 */
	GLPreview *glPreview;
	/**
	 * Show a single time serie
	 */
	GLLSPGraph *glLSPGraph;
	/**
	 * Map each name of the TSData to the particular TSData object
	 */
	QMap<QString, TSData*> mapNames2TSData;
	/**
	 * Use this map in order to generate fresh names
	 */
	QMap<QString, int> mapNameIndex;
	/**
	 * Line Graph and Preview zoom factor
	 */
	double lineGraphZoomFactor;
	/**
	 * Number of control points used for the LSP projection
	 */
	int controlPointsSize;

	/**
	 * Index of the active color
	 */
	int colorIndex;
	/**
	 * @brief				Generate a fresh name for data series
	 *
	 * Enusre that each time a series has been added to the system,
	 * a new name has been alocated for that TS
	 */
	QString getFreshName(QString name);

public:
	/**
	 * @brief construct a TSView with a particular file name
	 *
	 * If the file name is left empty, the view will create a new
	 * view, where all the parameters can be saved for latter use
	 */
	TSView(QWidget *parent, QString fileName = "");
	/**
	 * @brief 				Generate a new color on each call of this function.
	 *
	 * Currently 8 * 256 colors are supported (that should be more than
	 * enough for the human eye).
	 *
	 * @return 				A brand new QColor
	 */
	QColor getColorByIndex();
	/**
	 * @brief 				Turn on/off the GLLineGraph
	 */
	void toggleLineGraph ();
	/**
	 * @brief 				Turn on/off the GLLSPGraph
	 */
	void toggleLSPGraph ();
	/**
	 * @brief 				Turn on/off the GLPreviewGraph
	 */
	void togglePreviewGraph ();
	/**
	 * @brief 				Show/hide the settings
	 */
	void toggleSettings ();
	/**
	 * Default destructor
	 */
	~TSView();

public slots:
	/**
	 * @brief 				Make a propper action when new series are being added into the system
	 * @param newSeries		Vector containing the newly-added series
	 */
	void slot_on_seriesAdded(QVector<TSData*> newSeries);

	/**
	 * @brief 				Handle the import file action
	 *
	 * Create TSData objects and create a TSData object which is rendered
	 * by the OpenGL widgets
	 */
	void on_cmdImport_clicked();

	/**
	 * @brief 				Overload the value change of the slider
	 */
	void on_sliderZoom_valueChanged(int percent);
	/**
	 * @brief Zoom-In in the Line Graph and in the Preview
	 */
	void on_cmdZoomInLineGraph_clicked();
	/**
	 * @brief Zoom-Out in the Line Graph and in the Preview
	 */
	void on_cmdZoomOutLineGraph_clicked();

	/**
	 * @brief change the range of the LineGraph
	 */
	void slot_on_glLineGraph_updateRange(double min, double max);

	/**
	 * @brief 				Overload the value change of the slider for control points
	 */
	void on_sliderCTRLPoints_valueChanged(int percent);
	/**
	 * @brief 				Overload the value change of the spin box for control points
	 */
	void on_spinCTRLPoints_valueChanged(int percent);

	/**
	 * @brief				Handle selected TSData provieded from the LSP graph
	 */
	void slot_on_selectTSData(QVector<TSData*>);

	/**
	 * @brief	Detect the changes of selection in the TSView and highlight the selected data
	 */
	void on_listData_itemSelectionChanged();

signals:
	/**
	 * @brief 				Signal that triggers added series in the TSView
	 */
	void seriesAdded(QVector<TSData*> data);
	/**
	 * @brief 				Signal that triggers added series in the Preview Graph
	 */
	void seriesAddedPreview(QVector<TSData*> data);
	/**
	 * @brief 				Signal that triggers added series in the Line Graph
	 */
	void seriesAddedLineGraph(QVector<TSData*> data);
	/**
	 * @brief 				Signal that triggers added series in the LSP Graph
	 */
	void seriesAddedLSPGraph(QVector<TSData*> data);
	/**
	 * @brief				Update the range of the Line Graph
	 */
	void glLineGraph_updateRange(double rangeMinX, double rangeMaxX);
	/**
	 * @brief				Signal the Line Grap to highlight particular data
	 */
	void glLineGraph_highlight(QVector<TSData*> data);
	/**
	 * @brief 				Change the zoom percentage in the preview graph
	 */
	void glPreview_percentChange(double value);
	/**
	 * @brief				Update the number of control points on the graph
	 */
	void CTRLPointsValueChanged(int value);

	/**
	 * Use the threaded data read object as a friend class
	 */
	friend class TSDataRead;
};

#endif // TSVIEW_H
